package com.kunchi.isb.service;

import com.kunchi.isb.base.dto.ISBDto;
import com.kunchi.isb.base.exception.ISBException;
import com.kunchi.isb.base.result.ISBResult;
import com.kunchi.isb.base.validate.ISBFieldError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import java.util.List;

/**
 * 基础Service,封装了通用的校验和异常处理逻辑.
 *
 * @author 王檬
 */
public class BaseISBService<T extends ISBDto> {

    protected static Logger logger = LoggerFactory.getLogger(BaseISBService.class);

    @FunctionalInterface
    public interface InnerService<T> {
        void doService(ISBResult isbResult, T param) throws Exception;
    }

    /**
     * 通用处理业务代码。
     *
     * @param methodName
     * @param param
     * @param is
     * @return
     */
    protected void dealService(
            String methodName,
            ISBResult isbResult,
            T param,
            BindingResult bindingResult,
            BaseISBService.InnerService<T> is) {

        logger.info(String.format("<------%s:%s ----Started", methodName, param.toString()));

        try {

            // 到了这一步发现参数验证没有通过,则直接收集出错信息并打断处理.
            if (bindingResult.getAllErrors().size() != 0) {

                List<FieldError> frList = bindingResult.getFieldErrors();
                List<ISBFieldError> ifrList = isbResult.getValidationErrors();
                for (FieldError fr :
                        frList) {
                    // 把经过简化过的异常对象放入到isbResult;
                    ifrList.add(new ISBFieldError(fr.getField(), fr.getDefaultMessage(), fr.getRejectedValue()));
                }

                logger.info(String.format("<------%s:%s ----Service Refused", methodName, param.toString()));
                isbResult.markRefused();
                return;
            }

            // 执行服务处理
            is.doService(isbResult, param);

            // 如果没有错误,就标记成功,就此处理结束.
            if (!bindingResult.hasFieldErrors() && isbResult.getValidationErrors().size() == 0) {
                logger.info(String.format("<------%s:%s ----Successful.", methodName, param.toString()));
                isbResult.markSuccess();
                return;
            } else {
                // 到了这一步,一定是验证环节出了问题,先标记服务拒绝,然后收集和处理异常信息.
                logger.info(String.format("<------%s:%s ----Service Refused", methodName, param.toString()));
                isbResult.markRefused();
                return;
            }

        } catch (ISBException e) {
            logger.error(String.format("<------%s:%s ----Service Exception." + System.currentTimeMillis(), methodName, param.toString()));
            isbResult.setException(e);
            isbResult.markFailed();
            return;
        } catch (Exception e) {
            logger.error(String.format("<------%s:%s ----Service Exception." + System.currentTimeMillis(), methodName, param.toString()));
            isbResult.setException(new ISBException(ISBException.UNKNOWN_ERROR_CODE, this.getClass().getName() + ":调用过程发生未知异常", e));
            isbResult.markFailed();
            return;
        } finally {
            // Do nothing....
        }

    }
}